/*
 * Presenter.java
 *
 * 07/11/2009
 */
package kg.sound.player.ui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.SwingUtilities;

import kg.sound.player.Config;
import kg.sound.player.Model;

import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.api.SubstanceSkin;
import org.jvnet.substance.skin.OfficeBlue2007Skin;
import org.jvnet.substance.skin.SkinInfo;


/**
 * @author fernando
 */
public class Presenter {
	
	private static final Logger LOGGER = 
			Logger.getLogger(Presenter.class.getName());
	
	private static final String DEFAULT_LAF_KEY = "DEFAULT_LAF";
	private static final Class<? extends SubstanceSkin> DEFAULT_SKIN = OfficeBlue2007Skin.class;
	
	public final static String PLAY_MEDIA = "PLAY_MEDIA";
	public final static String PLAY_MEDIA_AS_CLIP = "PLAY_MEDIA_AS_CLIP";
	public final static String ADD_MEDIA = "ADD_MEDIA";
	public final static String REMOVE_MEDIA = "REMOVE_MEDIA";
	public final static String CLEAR_PLAYLIST = "CLEAR_PLAYLIST";
	public final static String STOP_MEDIA = "STOP_MEDIA";
	public final static String EXIT = "EXIT";
	public final static String CHANGE_LAF = "CHANGE_LAF";

	private final Model model;
	private final View view;

	private final List<ActionListener> listeners = new ArrayList<ActionListener>();

	public Presenter(Model model, View view) {
		this.model = model;
		this.view = view;
		init();
	}

    public Model getModel() {
        return model;
    }
    
    public View getView() {
    	return view;
    }

	private void init() {
		applyDefaultLaf();
		
		view.getPlaylist().setModel(new ListModelAdapter.Playlist(model));
		view.getPlayingNow().setModel(new ListModelAdapter.PlayingNow(model));
		view.getLafChooser().setModel(new LafModel());
		
		view.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				view.getButtonExit().doClick();
			}
		});
		
		view.getButtonAdd().setActionCommand(ADD_MEDIA);
		view.getButtonRemove().setActionCommand(REMOVE_MEDIA);
		view.getButtonPlay().setActionCommand(PLAY_MEDIA);
		view.getButtonPlayAsClip().setActionCommand(PLAY_MEDIA_AS_CLIP);
		view.getButtonStop().setActionCommand(STOP_MEDIA);
		view.getButtonClearPlaylist().setActionCommand(CLEAR_PLAYLIST);
		view.getButtonExit().setActionCommand(EXIT);
		view.getLafChooser().setActionCommand(CHANGE_LAF);
		
		ActionListener handler = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				notifyActionPerformed(e);
			}
		};
		
		view.getButtonAdd().addActionListener(handler);
		view.getButtonRemove().addActionListener(handler);
		view.getButtonPlay().addActionListener(handler);
		view.getButtonPlayAsClip().addActionListener(handler);
		view.getButtonStop().addActionListener(handler);
		view.getButtonClearPlaylist().addActionListener(handler);
		view.getButtonExit().addActionListener(handler);
		view.getLafChooser().addActionListener(handler);
		
		view.getLafChooser().addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				SkinInfo info = 
						(SkinInfo) view.getLafChooser().getSelectedItem();
				if (info != null) {
					applyLaf(info.getClassName());
				}
			}
		});
	}
		
	public void applyDefaultLaf() {
		
		/* Apply a user LAF, unless it's not supported */
		String userLaf = Config.getString(DEFAULT_LAF_KEY);
		if (userLaf != null) {
			applyLaf(userLaf);
		} else {
			/* Default LAF */ 
			applyLaf(DEFAULT_SKIN);
		}
	}
	
	public void applyLaf(String skinClassName) {
		try {
			applyLaf(Class.forName(skinClassName));
		} catch (ClassNotFoundException e) {
			String message = 
				"Could not load the Look And Feel: " + skinClassName;
		
			LOGGER.log(Level.SEVERE, message, e);
			Notification.getInstance().addMessage(message);
		}
	}
	
	public void applyLaf(final Class<?> skin) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					SubstanceLookAndFeel.setSkin(
							(SubstanceSkin) skin.newInstance());
				} catch (Exception e) {
					String message = 
							"Could not load the Look And Feel: " + skin.getName();
					
					LOGGER.log(Level.SEVERE, message, e);
					Notification.getInstance().addMessage(message);
				}
			}
		});
		Config.setString(DEFAULT_LAF_KEY, skin.getName());
	}
	
	public void addListener(ActionListener l) {
		listeners.add(l);
	}
	
	public void removeListener(ActionListener l) {
		listeners.remove(l);
	}
	
	public void notifyActionPerformed(ActionEvent e) {
		for (ActionListener l : listeners) {
			l.actionPerformed(e);
		}
	}

	public void dispose() {
		view.dispose();
	}
	
	public File[] getSelectedFilesInPlaylist() {
		Object itens[] = getView().getPlaylist().getSelectedValues();
		File files[] = new File[itens.length];
		for (int i = 0; i < itens.length; i++) {
			files[i] = (File) itens[i];
		}
		return files;
	}
	
	public File[] getSelectedFilesInPlayingNow() {
		Object itens[] = getView().getPlayingNow().getSelectedValues();
		File files[] = new File[itens.length];
		for (int i = 0; i < itens.length; i++) {
			files[i] = (File) itens[i];
		}
		return files;
	} 
}
